#include <glib.h>

#define TEST_GLIB_SEQUENCE_NUM 5

typedef struct my_data_tag {
    gint id;
    gchar *name;
}my_data_t;

gint _sequence_iter_cmp_func(GSequenceIter *a, GSequenceIter *b, gpointer data)
{
    my_data_t *d1, *d2;
    d1 = g_sequence_get(a);
    d2 = g_sequence_get(b);

    g_return_if_fail(d1);
    g_return_if_fail(d2);

    g_print("(%s)a:%d, b:%d \n", (gchar *)data, d1->id, d2->id);

    return d1->id - d2->id;
}


void _data_foreach_func(gpointer data, gpointer user_data)
{
    my_data_t *d = (my_data_t *)data;
    if(NULL != d) {
        g_print("(foreach)id:%d name:%s \n", d->id, d->name);
    }
}
void _data_destroy_func(gpointer data)
{
    my_data_t *d = (my_data_t *)data;
    g_return_if_fail(d);

    if(NULL != d->name) {
        g_print("(_data_destroy_func)id:%d name:%s \n", d->id, d->name);
        g_free(d->name);
    }
    g_free(d);
}

static void test_glib_sequence_iter(void)
{
    gint i;
    GSequence *seq = NULL;
    GSequenceIter *iter = NULL;
    GSequenceIter *iter_begin, *iter_end;
    my_data_t *d[TEST_GLIB_SEQUENCE_NUM];
    my_data_t *tmp = NULL;


    for(i=0;i<TEST_GLIB_SEQUENCE_NUM;i++) {
        d[i] = g_new0(my_data_t, 1);
        d[i]->id = i;
        d[i]->name = g_strdup_printf("name-%d", d[i]->id);
    }

    seq = g_sequence_new(_data_destroy_func);
    g_sequence_append(seq, (gpointer)d[2]);
    iter = g_sequence_append(seq, (gpointer)d[0]);
    g_sequence_insert_before(iter, (gpointer)d[3]);
    g_sequence_prepend(seq, (gpointer)d[1]);
    g_sequence_prepend(seq, (gpointer)d[4]);

    /* 4 1 2 3 0 */
    g_print("foreach \n");
    g_sequence_foreach(seq, _data_foreach_func, NULL);

    g_print("iter \n");
    iter = g_sequence_get_begin_iter (seq);
    while (!g_sequence_iter_is_end (iter)) {
        tmp = g_sequence_get(iter);
        if(NULL != tmp) {
            g_print("(iter)id:%d name:%s \n", tmp->id, tmp->name);
        }
        iter = g_sequence_iter_next (iter);
    }

    g_print("free \n");
    g_sequence_free(seq);
}

gint main(gint argc, gchar **argv) 
{
    test_glib_sequence_iter();

    return 0;
}
